package com.lmf.mock.starter.autoconfigure.controller;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lmf.mock.starter.autoconfigure.MockProperties;
import com.lmf.mock.starter.autoconfigure.entity.MockApi;
import com.lmf.mock.starter.autoconfigure.service.MockApiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Mock接口控制器 - 处理实际的Mock请求
 */
@RestController
public class MockController {

    @Autowired
    private MockApiService mockApiService;

    @Resource
    private MockProperties mockProperties;

    private final ObjectMapper objectMapper = new ObjectMapper();

    public String removeMockPrefix(String contextPath , String input) {
        String path = contextPath + mockProperties.getBasePath();
        if (input.startsWith(path)) {
            return input.substring(path.length()); // "/mock" 长度为 5
        }
        return input; // 如果不以 /mock 开头，原样返回
    }

    /**
     * 通用Mock接口处理器
     */
    @RequestMapping(value = "${mock.base-path:/mockI}/**",
            method = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE})
    public ResponseEntity<String> handleMockRequest(HttpServletRequest request) {
        String contextPath = request.getContextPath();
        String path = removeMockPrefix(contextPath,request.getRequestURI());
        String method = request.getMethod();
        
        // 提取请求参数
        Map<String, Object> requestParams = extractRequestParams(request);
        
        // 查找匹配的Mock接口（基于参数匹配）
        MockApi mockApi = mockApiService.getApiByPathMethodAndParams(path, method, requestParams);
        
        if (mockApi == null) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND)
                    .body("Mock接口未找到: " + method + " " + path);
        }
        
        // 处理延迟
        if (mockApi.getDelayMs() != null && mockApi.getDelayMs() > 0) {
            try {
                TimeUnit.MILLISECONDS.sleep(mockApi.getDelayMs());
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        
        // 返回Mock数据
        String responseData = mockApi.getResponseData();
        if (responseData == null) {
            responseData = "{}";
        }
        
        return ResponseEntity.status(mockApi.getStatusCode())
                .body(responseData);
    }

    /**
     * 提取请求参数（URL参数 + Body参数）
     */
    private Map<String, Object> extractRequestParams(HttpServletRequest request) {
        Map<String, Object> params = new HashMap<>();
        
        // 提取URL参数
        Map<String, String[]> parameterMap = request.getParameterMap();
        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
            String key = entry.getKey();
            String[] values = entry.getValue();
            if (values.length == 1) {
                params.put(key, values[0]);
            } else if (values.length > 1) {
                params.put(key, values);
            }
        }
        
        // 对于POST/PUT请求，尝试提取Body参数
        if ("POST".equalsIgnoreCase(request.getMethod()) || "PUT".equalsIgnoreCase(request.getMethod())) {
            try {
                String contentType = request.getContentType();
                if (contentType != null && contentType.contains("application/json")) {
                    // 解析JSON Body
                    String body = StreamUtils.copyToString(request.getInputStream(), StandardCharsets.UTF_8);
                    if (body != null && !body.trim().isEmpty()) {
                        Map<String, Object> bodyParams = objectMapper.readValue(body, new TypeReference<Map<String, Object>>() {});
                        params.putAll(bodyParams);
                    }
                }
            } catch (IOException e) {
                // 忽略Body解析错误，只使用URL参数
            }
        }
        
        return params;
    }
}
